package com.daigoudao.web.action;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.daigoudao.util.Constants;
import com.daigoudao.util.SequenceUtil;
import com.daigoudao.web.common.BaseAction;
import com.daigoudao.web.model.AddressModel;
import com.daigoudao.web.model.CanBuyModel;
import com.daigoudao.web.model.Cart;
import com.daigoudao.web.model.CartItem;
import com.daigoudao.web.model.EvaluateModel;
import com.daigoudao.web.model.InviteModel;
import com.daigoudao.web.model.Logistics;
import com.daigoudao.web.model.OrderDetailModel;
import com.daigoudao.web.model.ShortMessage;
import com.daigoudao.web.model.SimpleBuyModel;
import com.daigoudao.web.model.TransInfoModel;
import com.daigoudao.web.model.UserAddrModel;
import com.daigoudao.web.model.UserModel;
import com.daigoudao.web.model.WantBuyModel;
import com.daigoudao.web.service.ICanBuyService;
import com.daigoudao.web.service.IInviteService;
import com.daigoudao.web.service.ISimpleBuyService;
import com.daigoudao.web.service.ITransInfoService;
import com.daigoudao.web.service.IUserAddrService;
import com.daigoudao.web.service.IWantBuyService;
import com.danga.MemCached.MemCachedClient;

/**
 * 交易操作类
 * 
 * @author zheng
 * 
 */
public class TransInfoAction extends BaseAction {

	private static final long serialVersionUID = 7711399714377008047L;

	private static Logger logger = LoggerFactory
			.getLogger(TransInfoAction.class);

	private IUserAddrService userAddrService;

	private ITransInfoService transInfoService;

	private ISimpleBuyService simpleBuyService;

	private IInviteService inviteService;

	private ICanBuyService canBuyService;

	private IWantBuyService wantBuyService;

	private EvaluateModel evaluateModel;

	private UserAddrModel userAddr;

	private List<UserAddrModel> userAddrs;

	private List<ShortMessage> messages;

	private CanBuyModel product;

	private UserAddrModel defaultAddr;

	private AddressModel address;

	private MemCachedClient memcachedClient;

	private TreeMap<String, String> params;

	/**
	 * 数量
	 */
	private int number;

	/**
	 * 小计
	 */
	private float subTotal;

	/**
	 * 支付金额
	 */
	private String payment;

	private String content;

	private int iid;

	private int cid;

	private int wid;

	private int sid;

	private int from;

	private int userType;
	
	/**
	 * 运费
	 */
	private double shippingCost;

	/**
	 * 交易流水号
	 */
	private String tid;

	private int brokerId;

	private int[] productIds;

	private Logistics logistics;

	private TransInfoModel order;
	
	private int state = -1;
	
	private int brokerEvaluation;
	
	private int userEvaluation;

	/**
	 * 委托代购
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String entrust() {
		UserModel userModel = getUserLogin();
		if (userModel == null) {
			session.put(Constants.URL, "entrust.htm?id=" + id);
			return LOGIN;
		}
		try {
			userAddrs = getUserAddrs(userModel);
			product = canBuyService.queryCanBuyDetail(id);
			subTotal = new BigDecimal(
					(product.getServiceFee() + product.getPrice()) * number)
					.floatValue();
			backUrl = "canBuyDetail.htm?id=" + id;
		} catch (Exception e) {
			logger.error("entrust error.", e);
			return ERROR;
		}

		return SUCCESS;
	}

	/**
	 * 接受邀约
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String acceptInvite() {
		UserModel userModel = getUserLogin();
		if (userModel == null) {
			session.put(Constants.URL, "acceptInvite.htm?id=" + id);
			return LOGIN;
		}
		try {
			userAddrs = getUserAddrs(userModel);
			InviteModel inviteModel = inviteService.selectInvite(id);
			product = canBuyService.queryCanBuyDetail(inviteModel.getCanId());
			wid = inviteModel.getWantId();
			sid = inviteModel.getSimpleId();
			iid = id;

			// 判断是搭车求购者接受邀约还是求购用户邀约
			if (inviteModel.getSimpleId() == 0) {
				WantBuyModel wantBuyModel = wantBuyService
						.queryWantBuyDetail(inviteModel.getWantId());
				number = wantBuyModel.getNumber();
			} else {
				SimpleBuyModel simpleBuyModel = simpleBuyService
						.querySimpleBuy(inviteModel.getSimpleId());

				number = simpleBuyModel.getNumber();
			}
			subTotal = new BigDecimal(
					(product.getServiceFee() + product.getPrice()) * number)
					.floatValue();
			backUrl = "initMyInviteinfo.htm";
		} catch (Exception e) {
			logger.error("acceptInvite error.", e);
			return ERROR;
		}
		return SUCCESS;
	}

	public String confirmOrder() {
		UserModel userModel = getUserLogin();
		if (userModel == null) {
			return LOGIN;
		}
		order.getBuyer().setUserid(getUserLogin().getUserid());
		order.setTransId(SequenceUtil.getCurSeq());
		try {
			if (0 == from) {
				tid = processNormal();
			} else {
				tid = processCart();
			}
		} catch (Exception e) {
			logger.error("confirmOrder error.", e);
			return ERROR;
		}

		return SUCCESS;
	}

	/**
	 * 支付宝同步通知接口
	 * 
	 * @return
	 */
	public String syncNotify() {
		try {
			transInfoService.processAlipay(request.getParameterMap());
			backUrl = "initBTradingInfo.htm";
		} catch (Exception e) {
			logger.error("syncNotify error.", e);
			return ERROR;
		}
		return SUCCESS;
	}

	/**
	 * 支付宝异步通知接口
	 * 
	 * @return
	 */
	public String asyncNotify() {
		if (logger.isDebugEnabled()) {
			logger.debug("enter the method asyncNotify");
		}
		try {
			transInfoService.processAlipay(request.getParameterMap());
			response.getWriter().println("success");
		} catch (Exception e) {
			logger.error("syncNotify error.", e);
			try {
				response.getWriter().println("fail");
			} catch (IOException e1) {
				logger.error("print error.", e1);
			}
		}
		if (logger.isDebugEnabled()) {
			logger.debug("exit the method asyncNotify");
		}
		return null;
	}

	/**
	 * 发货
	 * 
	 * @return
	 */
	public String delivery() {
		if (!isLogin()) {
			return LOGIN;
		}
		TransInfoModel transInfoModel = new TransInfoModel();
		transInfoModel.setTransId(tid);
		transInfoModel.setState(2);
		transInfoModel.setSendTime(new Date());
		try {
			transInfoService.updateStatus(transInfoModel);
		} catch (Exception e) {
			logger.error("delivery error", e);
			return ERROR;
		}
		forwardUrl = "initTradingInfo.htm";
		return SUCCESS;
	}

	/**
	 * 确认收货
	 * 
	 * @return
	 */
	public String receipt() {
		if (!isLogin()) {
			return LOGIN;
		}
		TransInfoModel transInfo = new TransInfoModel();
		transInfo.setTransId(tid);
		transInfo.setState(3);
		transInfo.setEndTime(new Date());
		transInfo.setUserEvaluation(1);
		transInfo.setBrokerEvaluation(1);
		try {
			transInfoService.updateStatus(transInfo);
		} catch (Exception e) {
			logger.error("receipt error.", e);
			return ERROR;
		}
		forwardUrl = "initBTradingInfo.htm";
		return SUCCESS;
	}

	/**
	 * 交易详情
	 * 
	 * @return
	 */
	public String queryTransDetail() {
		UserModel user = getUserLogin();
		if (user == null) {
			return LOGIN;
		}
		TransInfoModel queryDetail = new TransInfoModel();
		queryDetail.setTransId(tid);
		if (Constants.USER_TYPE_BROKER == userType) {
			queryDetail.getBroker().setUserid(user.getUserid());
		} else {
			queryDetail.getBuyer().setUserid(user.getUserid());
		}
		try {
			order = transInfoService.queryOrderDetail(queryDetail);
			if (order == null) {
				return ERROR;
			}
			if (Constants.USER_TYPE_BROKER == userType) {
				return "detail1";
			} else {
				return "detail2";
			}
		} catch (Exception e) {
			logger.error("queryTransDetail error.", e);
			return ERROR;
		}
	}

	@SuppressWarnings("unchecked")
	public String cashier() {
		if (!isLogin()) {
			session.put(Constants.URL, "cashier.htm?tid=" + tid);
			return LOGIN;
		}

		try {
			params = transInfoService.getPayment(tid);
			payment = params.get(Constants.TOTAL_FEE);
		} catch (Exception e) {
			logger.error("cashier error.", e);
			return ERROR;
		}
		if (params.containsKey(Constants.ERR_MSG)) {
			logger.error("cashier error, error msg is {}",
					params.get(Constants.ERR_MSG));
			return ERROR;
		}
		return SUCCESS;
	}

	/**
	 * 取消订单
	 * 
	 * @return
	 */
	public String cancel() {
		TransInfoModel transInfoModel = new TransInfoModel();
		transInfoModel.setState(4);
		transInfoModel.setTransId(tid);
		try {
			transInfoService.updateStatus(transInfoModel);
		} catch (Exception e) {
			logger.error("cancel order error.", e);
			return ERROR;
		}
		forwardUrl = "initBTradingInfo.htm";
		return SUCCESS;
	}

	/**
	 * 设置默认地址
	 * 
	 * @return
	 */
	public String setDefaultAddrForAjax() {
		try {
			userAddrService.setDefaultAddr(userAddr);
		} catch (Exception e) {
			logger.error("setDefaultAddr error", e);
		}
		return SUCCESS;
	}

	public String saveAddrForAjax() {
		// 合并地址
		userAddr.setAddress(userAddr.getProvince() + userAddr.getCity()
				+ userAddr.getStreet());
		try {
			userAddrService.saveAddr(userAddr);
		} catch (Exception e) {
			logger.error("saveAddr", e);
		}
		return SUCCESS;
	}

	/**
	 * 评价
	 * 
	 * @return
	 */
	public String evaluate() {
		if (!isLogin()) {
			return LOGIN;
		}
		UserModel user = getUserLogin();
		try {

			TransInfoModel order = new TransInfoModel();
			order.setTransId(tid);
			if (Constants.USER_TYPE_BROKER == userType) {
				order.getBroker().setUserid(user.getUserid());
			} else {
				order.getBuyer().setUserid(user.getUserid());
			}
			order = transInfoService.queryOrderDetail(order);
			if (order == null) {
				return ERROR;
			}

			evaluateModel.getEvaluator().setUserid(user.getUserid());
			if (Constants.USER_TYPE_BROKER == userType) {
				evaluateModel.getEvaluatedUser().setUserid(
						order.getBuyer().getUserid());

				order.setUserEvaluation(2);
			} else {
				evaluateModel.getEvaluatedUser().setUserid(
						order.getBroker().getUserid());
				order.setBrokerEvaluation(2);
			}
			evaluateModel.setOrderId(order.getOrderId());
			transInfoService.evaluate(order, evaluateModel);
		} catch (Exception e) {
			logger.error("evaluate error.", e);
			return ERROR;
		}
		if (2 == userType) {
			forwardUrl = "initTradedInfo.htm";
		} else {
			forwardUrl = "initBTradedInfo.htm";
		}
		return SUCCESS;
	}

	/**
	 * 处理普通的订单确认
	 * 
	 * @return
	 * @throws Exception
	 */
	private String processNormal() throws Exception {
		CanBuyModel product = canBuyService.queryCanBuyDetail(cid);

		OrderDetailModel orderDetail = new OrderDetailModel();
		orderDetail.setGoodsName(product.getGoodsName());
		if (product.getImages() != null && product.getImages().size() > 0) {
			orderDetail.setImage(product.getImages().get(0));
		}
		orderDetail.setNumber(number);
		orderDetail.setPrice(product.getPrice());
		orderDetail.setServiceFee(product.getServiceFee());
		orderDetail.setProductId(product.getCanId());
		order.getOrderDetails().add(orderDetail);

		return transInfoService.addOrder(order);
	}

	/**
	 * 处理代购车结算订单确认
	 * 
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private String processCart() throws Exception {
		Cart cart = getCart(memcachedClient, getUserLogin().getUserid());
		if (cart.getCount() == 0) {
			return ERROR;
		}
		Map<Integer, CartItem> items = cart.getItems(order.getBroker()
				.getUserid());
		for (int productId : productIds) {
			if (items.containsKey(productId)) {
				CartItem item = items.get(productId);
				OrderDetailModel orderDetail = new OrderDetailModel();
				orderDetail.setGoodsName(item.getProductName());
				orderDetail.setImage(item.getImage());
				orderDetail.setNumber(item.getNumber());
				orderDetail.setPrice(item.getPrice());
				orderDetail.setProductId(item.getProductId());
				orderDetail.setServiceFee(item.getServiceFee());
				order.getOrderDetails().add(orderDetail);
			}
		}
		String transId = transInfoService.addOrder(order);

		// 删除代购车中相应的商品
		cart.delItems(order.getBroker().getUserid(), productIds);
		addCart(memcachedClient, cart, getUserLogin().getUserid());
		session.put(Constants.CART, cart.getCount());
		return transId;
	}

	/**
	 * 获取地址信息
	 * 
	 * @param userModel
	 * @return
	 */
	private List<UserAddrModel> getUserAddrs(UserModel userModel) {
		List<UserAddrModel> userAddrs = userAddrService
				.getAddrListByUserID(userModel.getUserid());
		// 将默认地址调整至第一个
		UserAddrModel userAddrModel = null;
		if (userAddrs != null && userAddrs.size() > 0) {
			defaultAddr = userAddrs.get(0);
			for (int i = 1; i < userAddrs.size(); i++) {
				if (userAddrs.get(i).getDefaultAddr() == 1) {
					userAddrModel = userAddrs.remove(i);
					break;
				}
			}
		}
		if (userAddrModel != null) {
			userAddrs.add(0, userAddrModel);
			defaultAddr = userAddrModel;
		}
		return userAddrs;
	}

	public EvaluateModel getEvaluateModel() {
		return evaluateModel;
	}

	public void setEvaluateModel(EvaluateModel evaluateModel) {
		this.evaluateModel = evaluateModel;
	}

	public UserAddrModel getUserAddr() {
		return userAddr;
	}

	public void setUserAddr(UserAddrModel userAddr) {
		this.userAddr = userAddr;
	}

	public List<UserAddrModel> getUserAddrs() {
		return userAddrs;
	}

	public void setUserAddrs(List<UserAddrModel> userAddrs) {
		this.userAddrs = userAddrs;
	}

	public List<ShortMessage> getMessages() {
		return messages;
	}

	public void setMessages(List<ShortMessage> messages) {
		this.messages = messages;
	}

	public CanBuyModel getProduct() {
		return product;
	}

	public void setProduct(CanBuyModel product) {
		this.product = product;
	}

	public UserAddrModel getDefaultAddr() {
		return defaultAddr;
	}

	public void setDefaultAddr(UserAddrModel defaultAddr) {
		this.defaultAddr = defaultAddr;
	}

	public AddressModel getAddress() {
		return address;
	}

	public void setAddress(AddressModel address) {
		this.address = address;
	}

	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	public String getPayment() {
		return payment;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public int getIid() {
		return iid;
	}

	public void setIid(int iid) {
		this.iid = iid;
	}

	public int getCid() {
		return cid;
	}

	public void setCid(int cid) {
		this.cid = cid;
	}

	public int getWid() {
		return wid;
	}

	public void setWid(int wid) {
		this.wid = wid;
	}

	public int getFrom() {
		return from;
	}

	public void setFrom(int from) {
		this.from = from;
	}

	public String getTid() {
		return tid;
	}

	public void setTid(String tid) {
		this.tid = tid;
	}

	public void setUserAddrService(IUserAddrService userAddrService) {
		this.userAddrService = userAddrService;
	}

	public void setTransInfoService(ITransInfoService transInfoService) {
		this.transInfoService = transInfoService;
	}

	public void setSimpleBuyService(ISimpleBuyService simpleBuyService) {
		this.simpleBuyService = simpleBuyService;
	}

	public void setInviteService(IInviteService inviteService) {
		this.inviteService = inviteService;
	}

	public void setCanBuyService(ICanBuyService canBuyService) {
		this.canBuyService = canBuyService;
	}

	public void setWantBuyService(IWantBuyService wantBuyService) {
		this.wantBuyService = wantBuyService;
	}

	public float getSubTotal() {
		return subTotal;
	}

	public int getUserType() {
		return userType;
	}

	public void setUserType(int userType) {
		this.userType = userType;
	}

	public Logistics getLogistics() {
		return logistics;
	}

	public void setLogistics(Logistics logistics) {
		this.logistics = logistics;
	}

	public int[] getProductIds() {
		return productIds;
	}

	public void setProductIds(int[] productIds) {
		this.productIds = productIds;
	}

	public void setMemcachedClient(MemCachedClient memcachedClient) {
		this.memcachedClient = memcachedClient;
	}

	public TransInfoModel getOrder() {
		return order;
	}

	public void setOrder(TransInfoModel order) {
		this.order = order;
	}

	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	public int getBrokerId() {
		return brokerId;
	}

	public void setBrokerId(int brokerId) {
		this.brokerId = brokerId;
	}

	public TreeMap<String, String> getParams() {
		return params;
	}

	public double getShippingCost() {
		return shippingCost;
	}

	public void setShippingCost(double shippingCost) {
		this.shippingCost = shippingCost;
	}

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	public int getBrokerEvaluation() {
		return brokerEvaluation;
	}

	public void setBrokerEvaluation(int brokerEvaluation) {
		this.brokerEvaluation = brokerEvaluation;
	}

	public int getUserEvaluation() {
		return userEvaluation;
	}

	public void setUserEvaluation(int userEvaluation) {
		this.userEvaluation = userEvaluation;
	}
	

	
}
